#!/usr/bin/env python

import sys
import DataConcattingHtmlParser

import pprint
import urllib2

ratingMap = {
    's0.gif': None,
    's1.gif': '0.5',
    's2.gif': '1',
    's3.gif': '1.5',
    's4.gif': '2',
    's5.gif': '2.5',
    's6.gif': '3',
    's7.gif': '3.5',
    's8.gif': '4',
    's9.gif': '4.5',
    's10.gif': '5',
    }

class PersonCatalogPageParser(DataConcattingHtmlParser.DataConcattingHtmlParser):
    def __init__(self, person):
        DataConcattingHtmlParser.DataConcattingHtmlParser.__init__(self)
        self.ratings = []

    def feed(self, data):
        self.lastUrl = None
        self.inBook = False
        self.inBookRow = False
        self.nextPage = None
        self.title = None
        self.work = None
        DataConcattingHtmlParser.DataConcattingHtmlParser.feed(self, data)

    def handle_starttag(self, tag, attrs):
        if tag == 'a' and dict(attrs).get('class', None) == 'lt-title':
            self.inBook = True
            self.inBookRow = True
            for attr in attrs:
                if attr[0] == 'href':
                    self.work = attr[1].split('/')[2].split('&')[0]
        elif tag == 'a':
            self.lastUrl = dict(attrs).get('href', None)
        elif self.inBookRow and tag == 'img' and attrs[0][0] == 'src':
            imgUrl = attrs[0][1]
            imageFile = imgUrl.split('/')[-1]
            if imageFile in ratingMap:
                self.ratings.append((self.title, ratingMap[imageFile], self.work))
                self.title = None
                self.work = None

    def handle_data(self, data):
        if self.inBook:
            self.title = data
            self.inBook = False;
        else:
            if data == 'next page':
                self.nextPage = self.lastUrl

    def handle_endtag(self, tag):
        if self.inBookRow:
            if tag == 'tr':
                self.inBookRow = False

class WorkRatingPageParser(DataConcattingHtmlParser.DataConcattingHtmlParser):
    def __init__(self, item):
        DataConcattingHtmlParser.DataConcattingHtmlParser.__init__(self)
        self.ratings = {}
        for score in ratingMap.values():
            if score is not None:
                self.ratings[score] = []

        self.currentRating = None
        
#     def feed(self, data):
#         self.lastUrl = None
#         self.inBook = False
#         self.inBookRow = False
#         self.nextPage = None
#         self.title = None
#         DataConcattingHtmlParser.DataConcattingHtmlParser.feed(self, data)

    def handle_starttag(self, tag, attrs):
        if tag == 'img':
            img = attrs[0][1].split('/')[-1]
            self.currentRating = ratingMap[img]
        elif tag == 'a' and self.currentRating is not None:
            self.ratings[self.currentRating].append(attrs[0][1].split('/')[-1])
        elif tag == 'b':
            self.currentRating = None


    def handle_data(self, data):
        pass

#     def handle_endtag(self, tag):
#         if self.inBookRow:
#             if tag == 'tr':
#                 self.inBookRow = False

site = 'http://www.librarything.com'
personLibraryUrlPattern = site + '/catalog_bottom.php?view=%(person)s'
workRatingUrlPattern = site + '/ajaxinc_userswithabook.php?work=%(work)s'

def loadPerson(person):
    url = personLibraryUrlPattern % vars()
    data = urllib2.urlopen(url).read()
    parser = PersonCatalogPageParser(person)
    parser.feed(data)
    while parser.nextPage:
        data = urllib2.urlopen(site + parser.nextPage).read()
        parser.feed(data)
    totalRatings = 0
    count = 0
    for t,r, w in parser.ratings:
        if r is not None:
            totalRatings += float(r)
            count +=1
            print t, r
        loadWorkRatings(w)

    if count > 0:
        print 'average:', totalRatings/count
    
def loadWorkRatings(work):
    url = workRatingUrlPattern % vars()
    data = urllib2.urlopen(url).read()
    parser = WorkRatingPageParser(work)
    parser.feed(data)
    pprint.pprint(parser.ratings)

def main(args=None):
    if args == None:
        args = sys.argv[1:]

    if len(args) == 0:
        person = 'Hippopottoman'
    else:
        person = args[0]
    
    loadPerson(person)
    loadWorkRatings('174924')


if __name__ == '__main__':
    sys.exit(main())

